package com.company.vmvp.api;

import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonSyntaxException;
import com.dee.components.LogUtils;

import org.apache.http.conn.ConnectTimeoutException;
import org.json.JSONException;

import java.io.IOException;
import java.io.NotSerializableException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.ParseException;

import retrofit2.HttpException;

public class RxException {

    private int code;
    private String message;

    public RxException(Throwable throwable) {
        this.message = throwable.getMessage();
        handleException(throwable);
    }

    public RxException(Throwable throwable, int code) {
        this.code = code;
        this.message = throwable.getMessage();
    }

    public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    private void handleException(Throwable e) {
        if (e instanceof HttpException) {
            HttpException httpException = (HttpException) e;
            this.code =httpException.code();
            try {
                this.message = httpException.response().errorBody().string();
            } catch (IOException e1) {
                e1.printStackTrace();
                this.message = e1.getMessage();
                getErrorMsg(httpException);
            }
        } else if (e instanceof SocketTimeoutException) {
            this.code= ERROR.TIMEOUT_ERROR;
            this.message = "网络连接超时，稍候重试！";
        } else if (e instanceof ConnectException) {
            this.code= ERROR.TIMEOUT_ERROR;
            this.message = "服务器无法连接，稍候重试！";
        } else if (e instanceof ConnectTimeoutException) {
            this.code= ERROR.TIMEOUT_ERROR;
            this.message = "网络连接超时，稍候重试！";
        } else if (e instanceof UnknownHostException) {
            this.code= ERROR.TIMEOUT_ERROR;
            this.message = "网络连接异常，请检查您的网络状态，稍候重试！";
        } else if (e instanceof NullPointerException) {
            this.code= ERROR.NULL_POINTER_EXCEPTION;
            this.message = "空指针异常";
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            this.code= ERROR.SSL_ERROR;
            this.message = "证书验证失败";
        } else if (e instanceof ClassCastException) {
            this.code= ERROR.CAST_ERROR;
            this.message = "类型转换错误";
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof JsonSyntaxException
                || e instanceof JsonSerializer
                || e instanceof NotSerializableException
                || e instanceof ParseException) {
            this.code= ERROR.PARSE_ERROR;
            this.message = "解析错误";
        } else if (e instanceof IllegalStateException) {
            this.code= ERROR.ILLEGAL_STATE_ERROR;
            this.message = e.getMessage();
        } else {
            this.code= ERROR.UNKNOWN;
            this.message = "未知错误";
        }
    }
    /**
     * 获取详细的错误的信息 errorCode,errorMsg 尝试UniCode转码
     * <p>
     * 以登录的时候的Grant_type 故意写错为例子,这个时候的http 应该是直接的返回401=httpException.code()
     * 但是是怎么导致401的？我们的服务器会在respose.errorBody 中的content 中说明
     */
    private final void getErrorMsg(HttpException httpException) {
        try {      //我们的项目需要的UniCode转码 ,!!!!!!!!!!!!!!
            this.message = convertUnicode(httpException.response().errorBody().string());
        } catch (IOException ioe) {
            LogUtils.eTag("errorBodyStr ioe:", ioe.toString());
        }
    }
    /**
     * 把含有Unicode 的字符串可视化
     *
     * @param ori
     * @return
     */
    public static String convertUnicode(String ori) {
        char aChar;
        int len = ori.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len; ) {
            aChar = ori.charAt(x++);
            if (aChar == '\\') {
                aChar = ori.charAt(x++);
                if (aChar == 'u') {
                    // Read the xxxx
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = ori.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed   \\uxxxx   encoding.");
                        }
                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't')
                        aChar = '\t';
                    else if (aChar == 'r')
                        aChar = '\r';
                    else if (aChar == 'n')
                        aChar = '\n';
                    else if (aChar == 'f')
                        aChar = '\f';
                    outBuffer.append(aChar);
                }
            } else
                outBuffer.append(aChar);

        }
        return outBuffer.toString();
    }

    /**
     * 约定异常
     */
    public static class ERROR {
        /**
         * 未知错误
         */
        public static final int UNKNOWN = 1000;
        /**
         * 连接超时
         */
        public static final int TIMEOUT_ERROR = 1001;
        /**
         * 空指针错误
         */
        public static final int NULL_POINTER_EXCEPTION = 1002;

        /**
         * 证书出错
         */
        public static final int SSL_ERROR = 1003;

        /**
         * 类转换错误
         */
        public static final int CAST_ERROR = 1004;

        /**
         * 解析错误
         */
        public static final int PARSE_ERROR = 1005;

        /**
         * 非法数据异常
         */
        public static final int ILLEGAL_STATE_ERROR = 1006;

    }
}
